import 'package:flutter/foundation.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:equatable/equatable.dart';
import 'package:syria_sports/presentation/tools/tools_page/models/tool.dart';

import '../../../../core/utils/show_toast.dart';
import '../../../../data/controllers/sports_controller.dart';
import '../../../../data/controllers/tools_controller.dart';
import '../../../exercises/exercises_page/models/exercise.dart';
import '../models/exercise_tool.dart';

part 'exercise_tools_state.dart';
part 'exercise_tools_event.dart';

class ExerciseToolsCubit extends Bloc<ExerciseToolsEvent, ExerciseToolsState> {
  ExerciseToolsCubit(ExerciseToolsState initialState) : super(ExerciseToolsInitial()){
    on<ExerciseToolsInitialEvent>(_onInitialize);
    on<GetExerciseToolsEvent>(_onGetSports);
    on<SelectModeEvent>(_onChangeSelectMode);
    on<SelectToolEvent>(_onSelectSport);
    on<AddToolToExerciseEvent>(_onAddGymToSport);
    on<DeleteToolsFromExerciseEvent>(_onDeleteToolsFromExercise);
    on<SelectAllToolsEvent>(_onSelectAllTools);
    on<UnSelectAllToolsEvent>(_onUnSelectAllTools);
  }

  static ExerciseToolsCubit get(context) => BlocProvider.of(context);
  List<ToolModel> tools = [];
  List<ToolModel> selectedTools = [];
  bool selectMode = false;
  late Exercise exercise;

  _onInitialize(
      ExerciseToolsInitialEvent event,
      Emitter<ExerciseToolsState> emit,
      )async {
    exercise = event.exercise;
    tools = [];
    emit(ExerciseToolsLoading());
    await ToolsController.getExerciseTools(exerciseId: exercise.exerciseId??"-1").catchError((e){
      emit(ExerciseToolsError());
      return null;
    }).then((value){
      if(value != null && value.state) {
        add(SelectModeEvent(mode: false));
        tools = List<ToolModel>.generate(value.data.length, (index) {
          var exeT =ExerciseTool.fromJson(value.data[index]);
          exeT.tool.exerciseToolId = exeT.exerciseToolId.toString();
          return exeT.tool;
        });
        emit(ExerciseToolsDone());
      }else if(value != null){
        showMessage(value.message);
        emit(ExerciseToolsError());
      }else{
        if (kDebugMode) {
          print('value is null ${value.runtimeType}');
        }
      }
    });
  }


  _onGetSports(
      GetExerciseToolsEvent event,
      Emitter<ExerciseToolsState> emit,
      )async{
    tools = [];
    emit(ExerciseToolsLoading());
    await SportsController.getAllSports().catchError((e){
      emit(ExerciseToolsError());
      return null;
    }).then((value){
      if(value != null && value.state) {
        tools = List<ToolModel>.generate(value.data.length, (index) => ToolModel.fromJson(value.data[index]));
        emit(ExerciseToolsDone());
      }else if(value != null){
        showMessage(value.message);
        emit(ExerciseToolsError());
      }else{
        if (kDebugMode) {
          print('value is null');
        }
      }
    });
  }

  _onAddGymToSport(
      AddToolToExerciseEvent event,
      Emitter<ExerciseToolsState> emit,
      )async{
    tools = [];
    emit(AddToolToExerciseLoading(sport: event.tool,gym:event.exercise ));
    await ToolsController.addToExercise(tool: event.tool, exercise: event.exercise).catchError((e){
      emit(AddToolToExerciseError(
          sport: event.tool,
          gym:event.exercise,
        massage: '',
        stateCode: -1,
      ));
      return null;
    }).then((value){
      if(value != null && value.state) {
        emit(AddToolToExerciseDone(sport: event.tool,gym:event.exercise ,gymSport:ExerciseTool.fromJson(value.data), ));
      }else if(value != null){
        showMessage(value.message);
        emit(AddToolToExerciseError(
          sport: event.tool,
          gym:event.exercise,
          massage: value.message,
          stateCode: -1,
        ));
      }else{
        if (kDebugMode) {
          print('value is null');
        }
      }
    });
  }


  _onDeleteToolsFromExercise(
      DeleteToolsFromExerciseEvent event,
      Emitter<ExerciseToolsState> emit,
      )async{
    //emit(AddToolToExerciseLoading(sport: event.tool,gym:event.exercise ));
    List<int> ids = selectedTools.map<int>((e) => int.tryParse(e.exerciseToolId.toString())??-1).toList();
    if(event.tool != null)ids = [int.tryParse((event.tool?.exerciseToolId).toString())??-1];
    await ToolsController.deleteByIds(ids).catchError((e){
      print(e);
      return null;
    }).then((value){
      if(value != null && value.state) {
        List data = value.data;
        var success = data.where((element) {
          tools.removeWhere((element1) => element1.exerciseToolId==element['exerciseToolId']);
          selectedTools.removeWhere((element1) => element1.exerciseToolId==element['exerciseToolId']);
          return element['state'];
        }).length;

        emit(ExerciseToolsDone());
        showMessage("نجح حذف ${success} عنصر وفشل ${data.length - success}");
      }else if(value != null){
        showMessage(value.message);
      }else{
        if (kDebugMode) {
          print('value is null');
        }
      }
    });
  }



  _onChangeSelectMode(
      SelectModeEvent event,
      Emitter<ExerciseToolsState> emit,
      )async{
    selectMode = event.mode;
    if(event.sport != null){
      selectedTools.add(event.sport!);
    }
    if(!event.mode){
      selectedTools.clear();
    }
    emit(SelectModeUpdate( mode: selectMode));
  }

  _onSelectSport(
      SelectToolEvent event,
      Emitter<ExerciseToolsState> emit,
      )async{
    if(event.isSelected){
      selectedTools.add(event.tool);
    }else{
      selectedTools.remove(event.tool);
    }
    emit(SelectTool(sport: event.tool,isSelected: event.isSelected));
  }
  _onSelectAllTools(
      SelectAllToolsEvent event,
      Emitter<ExerciseToolsState> emit,
      )async{
    selectedTools = [...tools];
    selectMode = true;
    emit(SelectModeUpdate( mode: true));
  }
  _onUnSelectAllTools(
      UnSelectAllToolsEvent event,
      Emitter<ExerciseToolsState> emit,
      )async{
    selectedTools = [];
    selectMode = false;
    emit(SelectModeUpdate( mode: false));
  }

  Future onRefresh()async{
    add(ExerciseToolsInitialEvent(exercise: exercise));
  }
}
